home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Tools 2
/
Amiga Tools 2.iso
/
tools
/
packer
/
ha0999beta
/
src
/
machine.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-09
|
12KB
|
472 lines
/***********************************************************************
This file is part of HA, a general purpose file archiver.
Copyright (C) 1995 Harri Hirvola
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
************************************************************************
HA *nix specific routines
***********************************************************************/
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
#include <utime.h>
#include <time.h>
#include "ha.h"
#include "error.h"
#include "archive.h"
#define HA_ISVTX 0x0200
#define HA_ISGID 0x0400
#define HA_ISUID 0x0800
#define HA_IRUSR 0x0100
#define HA_IWUSR 0x0080
#define HA_IXUSR 0x0040
#define HA_IRGRP 0x0020
#define HA_IWGRP 0x0010
#define HA_IXGRP 0x0008
#define HA_IROTH 0x0004
#define HA_IWOTH 0x0002
#define HA_IXOTH 0x0001
#define HA_IFMT 0xf000
#define HA_IFIFO 0x1000
#define HA_IFCHR 0x2000
#define HA_IFDIR 0x4000
#define HA_IFBLK 0x6000
#define HA_IFREG 0x8000
#define HA_IFLNK 0xa000
#define HA_IFSOCK 0xc000
#define HA_ISDIR(m) ((m&HA_IFMT)==HA_IFDIR)
#define HA_ISCHR(m) ((m&HA_IFMT)==HA_IFCHR)
#define HA_ISBLK(m) ((m&HA_IFMT)==HA_IFBLK)
#define HA_ISLNK(m) ((m&HA_IFMT)==HA_IFLNK)
#define HA_ISFIFO(m) ((m&HA_IFMT)==HA_IFIFO)
#define HA_ISSOCK(m) ((m&HA_IFMT)==HA_IFSOCK)
typedef struct {
unsigned mtype;
unsigned attr;
unsigned user;
unsigned group;
} Mdhd;
#define MDHDLEN 7 /* Length of Mdhd in archive */
static Mdhd mdhd;
struct stat filestat;
static void sig_handler(int signo) {
error(1,ERR_INT,signo);
}
void md_init(void) {
signal(SIGINT,sig_handler);
signal(SIGTERM,sig_handler);
signal(SIGPIPE,sig_handler);
signal(SIGQUIT,sig_handler);
umask(0);
}
U32B md_systime(void) {
return (U32B)time(NULL);
}
static mode_t md_tomdattr(U16B haattr) {
mode_t mdattr;
mdattr=0;
if (haattr&HA_IRUSR) mdattr|=S_IRUSR;
if (haattr&HA_IWUSR) mdattr|=S_IWUSR;
if (haattr&HA_ISUID) mdattr|=S_ISUID;
if (haattr&HA_IXUSR) mdattr|=S_IXUSR;
if (haattr&HA_IRGRP) mdattr|=S_IRGRP;
if (haattr&HA_IWGRP) mdattr|=S_IWGRP;
if (haattr&HA_ISGID) mdattr|=S_ISGID;
if (haattr&HA_IXGRP) mdattr|=S_IXGRP;
if (haattr&HA_IROTH) mdattr|=S_IROTH;
if (haattr&HA_IWOTH) mdattr|=S_IWOTH;
#ifdef S_ISVTX
if (haattr&HA_ISVTX) mdattr|=S_ISVTX;
#endif
if (haattr&HA_IXOTH) mdattr|=S_IXOTH;
return mdattr;
}
static U16B md_tohaattr(mode_t mdattr) {
U16B haattr;
haattr=0;
if (mdattr&S_IRUSR) haattr|=HA_IRUSR;
if (mdattr&S_IWUSR) haattr|=HA_IWUSR;
if (mdattr&S_ISUID) haattr|=HA_ISUID;
if (mdattr&S_IXUSR) haattr|=HA_IXUSR;
if (mdattr&S_IRGRP) haattr|=HA_IRGRP;
if (mdattr&S_IWGRP) haattr|=HA_IWGRP;
if (mdattr&S_ISGID) haattr|=HA_ISGID;
if (mdattr&S_IXGRP) haattr|=HA_IXGRP;
if (mdattr&S_IROTH) haattr|=HA_IROTH;
if (mdattr&S_IWOTH) haattr|=HA_IWOTH;
if (mdattr&S_IXOTH) haattr|=HA_IXOTH;
#ifdef S_ISVTX
if (mdattr&S_ISVTX) haattr|=HA_ISVTX;
#endif
if (S_ISDIR(mdattr)) haattr|=HA_IFDIR;
else if (S_ISCHR(mdattr)) haattr|=HA_IFCHR;
else if (S_ISBLK(mdattr)) haattr|=HA_IFBLK;
#ifdef S_ISLNK
else if (S_ISLNK(mdattr)) haattr|=HA_IFLNK;
#endif
#ifdef S_ISFIFO
else if (S_ISFIFO(mdattr)) haattr|=HA_IFIFO;
#endif
#ifdef S_ISSOCK
else if (S_ISSOCK(mdattr)) haattr|=HA_IFSOCK;
#endif
return haattr;
}
static char *attrstring(unsigned haattr) {
static char as[11];
sprintf(as,"%c%c%c%c%c%c%c%c%c%c",
HA_ISFIFO(haattr)?'f':HA_ISSOCK(haattr)?'s':HA_ISLNK(haattr)?'l':
HA_ISDIR(haattr)?'d':HA_ISCHR(haattr)?'c':HA_ISBLK(haattr)?'b':'-',
(haattr&HA_IRUSR)?'r':'-',
(haattr&HA_IWUSR)?'w':'-',
(haattr&HA_ISUID)?(haattr&
HA_IXUSR)?'s':'S':(haattr&HA_IXUSR)?'x':'-',
(haattr&HA_IRGRP)?'r':'-',
(haattr&HA_IWGRP)?'w':'-',
(haattr&HA_ISGID)?(haattr&
HA_IXGRP)?'s':'S':(haattr&HA_IXGRP)?'x':'-',
(haattr&HA_IROTH)?'r':'-',
(haattr&HA_IWOTH)?'w':'-',
(haattr&HA_ISVTX)?(haattr&
HA_IXOTH)?'t':'T':(haattr&HA_IXOTH)?'x':'-'
);
return as;
}
void md_gethdr(int len, int mode) {
static int longest=0;
static unsigned char *buf=NULL;
if (len>longest) {
if (buf!=NULL) buf=realloc(buf,len);
else buf=malloc(len);
if (buf==NULL) error(1,ERR_MEM,"md_gethdr()");
longest=len;
}
read(arcfile,buf,len);
mdhd.mtype=buf[0];
if (mdhd.mtype==UNIXMDH) {
mdhd.attr=buf[1]|(buf[2]<<8);
mdhd.user=buf[3]|(buf[4]<<8);
mdhd.group=buf[5]|(buf[6]<<8);
}
else {
switch (mode) {
case M_DIR:
mdhd.attr=md_tohaattr(DEF_DIRATTR);
mdhd.attr|=HA_IFDIR;
break;
default:
mdhd.attr=md_tohaattr(DEF_FILEATTR);
break;
}
}
}
void md_puthdr(void) {
unsigned char buf[MDHDLEN];
buf[0]=UNIXMDH;
buf[1]=mdhd.attr&0xff;
buf[2]=(mdhd.attr>>8)&0xff;
buf[3]=mdhd.user&0xff;
buf[4]=(mdhd.user>>8)&0xff;
buf[5]=mdhd.group&0xff;
buf[6]=(mdhd.group>>8)&0xff;
write(arcfile,buf,MDHDLEN);
}
int md_filetype(char *path, char *name) {
char *fullpath;
if (!strcmp(name,".") || !strcmp(name,"..")) return T_SKIP;
fullpath=md_pconcat(0,path,name);
if (lstat(fullpath,&filestat)<0) {
error(0,ERR_STAT,fullpath);
free(fullpath);
return T_SKIP;
}
free(fullpath);
if (filestat.st_ino==arcstat.st_ino) return T_SKIP;
if (S_ISDIR(filestat.st_mode)) return T_DIR;
if (S_ISREG(filestat.st_mode)) return T_REGULAR;
return T_SPECIAL;
}
int md_newfile(void) {
mdhd.attr=md_tohaattr(filestat.st_mode);
mdhd.user=filestat.st_uid;
mdhd.group=filestat.st_gid;
return MDHDLEN;
}
int md_special(char *fullname, unsigned char **sdata) {
static unsigned char *dat=NULL;
int len;
if (dat!=NULL) {
free(dat);
dat=NULL;
}
if (HA_ISCHR(mdhd.attr)||HA_ISBLK(mdhd.attr)) {
if ((dat=malloc(sizeof(dev_t)))==NULL) error(1,ERR_MEM,"md_special()");
*(dev_t*)dat=filestat.st_rdev;
*sdata=dat;
return sizeof(dev_t);
}
if (HA_ISLNK(mdhd.attr)) {
if ((dat=malloc(1024))==NULL) error(1,ERR_MEM,"md_special()");
if ((len=readlink(fullname,(char*)dat,1024))<0)
error(1,ERR_RDLINK,fullname);
dat[len]=0;
*sdata=dat;
return len+1;
}
else {
*sdata=dat;
return 0;
}
}
int md_mkspecial(char *ofname,unsigned sdlen,unsigned char *sdata) {
if (mdhd.mtype!=UNIXMDH) {
error(0,ERR_HOW,ofname);
return 0;
}
if (HA_ISCHR(mdhd.attr)) {
mknod(ofname,md_tomdattr(mdhd.attr)|S_IFCHR,*(dev_t*)sdata);
if (useattr) chown(ofname,mdhd.user,mdhd.group);
return 1;
}
else if (HA_ISBLK(mdhd.attr)) {
mknod(ofname,md_tomdattr(mdhd.attr)|S_IFBLK,*(dev_t*)sdata);
if (useattr) chown(ofname,mdhd.user,mdhd.group);
return 1;
}
#ifdef S_ISLNK
else if (HA_ISLNK(mdhd.attr)) {
if (symlink(ofname,(char*)sdata)<0) error(0,ERR_MKLINK,sdata,ofname);
if (useattr) {
chmod(ofname,md_tomdattr(mdhd.attr));
chown(ofname,mdhd.user,mdhd.group);
}
return 1;
}
#endif
#ifdef S_ISFIFO
else if (HA_ISFIFO(mdhd.attr)) {
if (mkfifo(ofname,md_tomdattr(mdhd.attr))<0)
error(0,ERR_MKFIFO,sdata,ofname);
if (useattr) chown(ofname,mdhd.user,mdhd.group);
return 1;
}
#endif
error(0,ERR_HOW,ofname);
return 0;
}
void md_setfattrs(char *file) {
if (useattr) {
chmod(file,md_tomdattr(mdhd.attr));
chown(file,mdhd.user,mdhd.group);
}
}
void md_setft(char *file,U32B time) {
struct utimbuf utb;
utb.actime=time;
utb.modtime=time;
utime(file,&utb);
}
void md_listhdr(void) {
printf("\n attr");
}
void md_listdat(void) {
printf("\n %s",attrstring(mdhd.attr));
}
char *md_timestring(unsigned long t) {
static char ts[22];
struct tm *tim;
tim=localtime((long *)&t);
sprintf(ts,"%04d-%02d-%02d %02d:%02d",tim->tm_year+1900,tim->tm_mon+1,
tim->tm_mday,tim->tm_hour,tim->tm_min);
return ts;
}
char *md_arcname(char *name_req) {
int pos;
char *newname;
pos=strlen(name_req);
if (pos>3 &&
tolower(name_req[pos-1])=='a' &&
tolower(name_req[pos-2])=='h' &&
name_req[pos-3]=='.') return name_req;
if ((newname=malloc(pos+4))==NULL) error(1,ERR_MEM,"md_arcname()");
strcpy(newname,name_req);
strcpy(newname+pos,".ha");
return newname;
}
void md_truncfile(int fh, U32B len) {
ftruncate(fh,len);
}
char *md_tohapath(char *mdpath) {
int i,j;
static char *hapath=NULL;
if (hapath!=NULL) free(hapath),hapath=NULL;
j=strlen(mdpath);
for (i=0;mdpath[i];++i) if (mdpath[i]!='.' && mdpath[i]!='/') break;
while (i>0 && mdpath[i-1]=='.') --i;
if (i==0) skipemptypath=1;
else skipemptypath=0;
if ((hapath=malloc(j+1-i))==NULL) error(1,ERR_MEM,"md_tohapath()");
strcpy(hapath,mdpath+i);
for (i=0;hapath[i];++i) if (hapath[i]=='/') hapath[i]=0xff;
return md_strcase(hapath);
}
char *md_tomdpath(char *hapath) {
int i;
static char *mdpath=NULL;
if (mdpath!=NULL) free(mdpath),mdpath=NULL;
if ((mdpath=malloc(strlen(hapath)+1))==NULL)
error(1,ERR_MEM,"md_tomdpath()");
strcpy(mdpath,hapath);
for (i=0;mdpath[i];++i) if ((unsigned char)mdpath[i]==0xff) mdpath[i]='/';
return mdpath;
}
char *md_strippath(char *mdfullpath) {
int i;
static char *plainpath=NULL;
if (plainpath!=NULL) free(plainpath),plainpath=NULL;
if ((plainpath=malloc(strlen(mdfullpath)+1))==NULL)
error(1,ERR_MEM,"md_strippath()");
strcpy(plainpath,mdfullpath);
for (i=strlen(plainpath)-1;i>=0;i--) {
if (plainpath[i]=='/') break;
}
plainpath[i+1]=0;
return plainpath;
}
char *md_stripname(char *mdfullpath) {
int i;
static char *plainname=NULL;
if (plainname!=NULL) free(plainname),plainname=NULL;
if ((plainname=malloc(strlen(mdfullpath)+1))==NULL)
error(1,ERR_MEM,"md_stripname()");
for (i=strlen(mdfullpath)-1;i>0;i--) {
if (mdfullpath[i]=='/') {
i++;
break;
}
}
strcpy(plainname,mdfullpath+i);
return plainname;
}
char *md_pconcat(int delim2, char *head, char *tail) {
char *newpath;
int headlen,delim1;
delim1=0;
if ((headlen=strlen(head))!=0) {
if (head[headlen-1]!='/') delim1=1;
}
if ((newpath=malloc(headlen+strlen(tail)+delim2+delim1+1))==NULL)
error(1,ERR_MEM,"md_pconcat()");
if (headlen!=0) strcpy(newpath,head);
if (delim1) newpath[headlen]='/';
strcpy(newpath+headlen+delim1,tail);
if (delim2) strcpy(newpath+strlen(newpath),"/");
return newpath;
}
int md_namecmp(char *pat, char *cmp) {
if (*pat==0) return !*cmp;
if (*pat=='?') {
if (!*cmp) return 0;
return md_namecmp(pat+1,cmp+1);
}
if (*pat=='*') {
if (*(pat+1)==0) return 1;
for (;*cmp;++cmp) {
if (md_namecmp(pat+1,cmp)) return 1;
}
return 0;
}
if (*pat=='\\') {
++pat;
if (*pat==0) return 0;
}
if (*pat==*cmp) return md_namecmp(pat+1,cmp+1);
return 0;
}